package com.potato.dashboard.dao.hibernate;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.potato.dashboard.dao.GenericDao;

public class HibernateGenericDao<T, PK extends Serializable> extends HibernateDaoSupport implements GenericDao<T, PK> {
	protected final Log log = LogFactory.getLog(getClass());
	private Class<T> persistentClass;

	@SuppressWarnings("unchecked")
	public HibernateGenericDao() {
		this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}

	@SuppressWarnings("unchecked")
	public T findById(PK id) {
		T entity = (T) super.getHibernateTemplate().get(this.persistentClass, id);

		if (entity == null) {
			log.warn("Uh oh, '" + this.persistentClass + "' object with id '" + id + "' not found...");
			throw new ObjectRetrievalFailureException(this.persistentClass, id);
		}

		return entity;
	}

	@SuppressWarnings("unchecked")
	public List<T> findAll() {
		return super.getHibernateTemplate().loadAll(this.persistentClass);
	}

	@SuppressWarnings("unchecked")
	public List<T> findByExample(T example) {
		return super.getHibernateTemplate().findByExample(example);
	}

	@SuppressWarnings("unchecked")
	public T save(T entity) {
		return (T) super.getHibernateTemplate().merge(entity);
	}

	public void remove(T entity) {
		super.getHibernateTemplate().delete(entity);
	}
}
